using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace RRHH.Competencias.DataAccessLayer.SqlServerProvider
{
    /// <summary>
    /// Clase para operar con Procedimientos Almacenados en SqlServer
    /// </summary>
    class DALSqlServerStoredProcedure
    {
        
        private string mNombreProcedimiento;
        private static List<DALSqlServerStoredProcedureParameter> mParametros;

        public DALSqlServerStoredProcedure(string pNombre)
        {
            try
            {                
                mNombreProcedimiento = pNombre;
                mParametros = new List<DALSqlServerStoredProcedureParameter>();
            }
            catch (Exception ex)
            {
                throw new DALException(ex.Message);
            }
        }

        #region Propiedades
        public string Nombre
        {
            get { return mNombreProcedimiento; }
            set { mNombreProcedimiento = value; }
        }

        public static List<DALSqlServerStoredProcedureParameter> Parametros
        {
            get { return mParametros; }
        }
        #endregion

        #region Metodos
        
        /// <summary>
        /// agrega un nuevo parametro.
        /// </summary>
        /// <param name="pVariable"></param>
        /// nombre del parametro
        /// <param name="pValor"></param>
        /// valor, el valor no puede ser null
        public void AgregarParametro(string pVariable, object pValor)
        {
            AgregarParametro(pVariable, pValor, pValor.GetType());
        }

        public void AgregarParametro(string pVariable, object pValor, Type pTipo)
        {
            DALSqlServerStoredProcedureParameter iParametro;
            iParametro = new DALSqlServerStoredProcedureParameter(pVariable, pValor, pTipo);
            
            Parametros.Add(iParametro);
        }

        /// <summary>
        /// Ejecuta un stored devolviendo un DataTable con el resultado
        /// </summary>
        /// <returns>DataTable con el resultado</returns>
        public DataTable ExecuteDataTable()
        {
            DALSqlServerConnection sqlConn;
            SqlCommand sqlComm = null;
            SqlDataAdapter sqlDataAdapter;
            DataTable table;
           
            try
            {
                sqlConn = new DALSqlServerConnection();
                
                sqlComm = new SqlCommand();
                sqlComm.Connection = sqlConn.Conexion;
                sqlComm.CommandType = CommandType.StoredProcedure;
                sqlComm.CommandText = Nombre;
                
                foreach (DALSqlServerStoredProcedureParameter oParametro in Parametros)
                {
                    sqlComm.Parameters.Add(oParametro.GetSqlParameter);
                }

                table = new DataTable();
                sqlDataAdapter = new SqlDataAdapter(sqlComm);

                sqlDataAdapter.Fill(table);

                return table;
            }
            catch (Exception ex)
            {
                throw new DALException(ex.Message);
            }
            finally
            {
                if (sqlComm != null && sqlComm.Connection != null && sqlComm.Connection.State == ConnectionState.Open)
                {
                    sqlComm.Connection.Close();
                    sqlComm.Dispose();
                }
            }
        }

        /// <summary>
        /// Ejecuta un Stored sin devolucion de valores
        /// </summary>
        public void ExecuteNonQuery()
        {
            DALSqlServerConnection sqlConn;
            SqlCommand sqlComm = null;
            SqlTransaction sqlTrans = null;
           
            try
            {
                sqlConn = new DALSqlServerConnection();

                sqlComm = new SqlCommand();
                sqlComm.Connection = sqlConn.Conexion;
                sqlComm.CommandType = CommandType.StoredProcedure;
                sqlComm.CommandText = Nombre;

                foreach (DALSqlServerStoredProcedureParameter oParametro in Parametros)
                {
                    sqlComm.Parameters.Add(oParametro.GetSqlParameter);
                }
                                
                sqlTrans = sqlComm.Connection.BeginTransaction();
                sqlComm.Transaction = sqlTrans;
                sqlComm.ExecuteNonQuery();
                sqlTrans.Commit();
            }
            catch (Exception ex)
            {
                if (sqlTrans != null) sqlTrans.Rollback();
                throw new DALException(ex.Message);
            }
            finally
            {
                if (sqlComm != null && sqlComm.Connection != null && sqlComm.Connection.State == ConnectionState.Open)
                {
                    sqlComm.Connection.Close();
                    sqlComm.Dispose();
                }
            }
        }

        /// <summary>
        /// Ejecuta un Stored y devuelve el valor obtenido en la primera columna y la primera fila
        /// </summary>
        /// <returns>Valor obtenido</returns>
        public object ExecuteScalar()
        { 
            DALSqlServerConnection sqlConn;
            SqlCommand sqlComm = null;
            SqlTransaction sqlTrans = null;
               
            try
            {
                sqlConn = new DALSqlServerConnection();

                sqlComm = new SqlCommand();
                sqlComm.Connection = sqlConn.Conexion;
                sqlComm.CommandType = CommandType.StoredProcedure;
                sqlComm.CommandText = Nombre;

                foreach (DALSqlServerStoredProcedureParameter oParametro in Parametros)
                {
                    sqlComm.Parameters.Add(oParametro.GetSqlParameter);
                }

                sqlTrans = sqlComm.Connection.BeginTransaction();
                sqlComm.Transaction = sqlTrans;
                Object resultado = sqlComm.ExecuteScalar();
                sqlTrans.Commit();

                return resultado;
            }
            catch (Exception ex)
            {
                if (sqlTrans != null) sqlTrans.Rollback();
                throw new DALException(ex.Message);
            }
            finally
            {
                if (sqlComm != null && sqlComm.Connection != null && sqlComm.Connection.State == ConnectionState.Open)
                {
                    sqlComm.Connection.Close();
                    sqlComm.Dispose();
                }
            }
        }
        #endregion
    }
}
